package com.luke.source.pattern;

/**
 * 装饰器模式
 *
 * 1、分为装饰者和被装饰者，他们两个都继承自同一个接口
 * 2、装饰者依赖被装饰者
 * 3、装饰器模式核心思想或者目的就是：重写某些方法，在装饰器的基础上进一步操作
 *
 * Netty中的使用
 * @see io.netty.buffer.WrappedByteBuf
 * @see io.netty.buffer.UnreleasableByteBuf
 * @see io.netty.buffer.SimpleLeakAwareByteBuf
 */
public class Decorate {

    public interface OnSalePlan {
        float getPrice(float oldPrice);
    }

    //无优惠
    public final static class NonePlan implements OnSalePlan {

        private NonePlan(){}

        static final OnSalePlan INSTANCE = new NonePlan();

        @Override
        public float getPrice(float oldPrice) {
            return oldPrice;
        }
    }

    //立减优惠
    public static class  KnockPlan implements OnSalePlan {
        //立减金额
        private float amount;

        public KnockPlan(float amount) {
            this.amount = amount;
        }

        @Override
        public float getPrice(float oldPrice) {
            return oldPrice - amount;
        }
    }

    //打折优惠（装饰者）
    public static class DiscountPlan implements OnSalePlan {

        //折扣值
        public int discount;

        //依赖被装饰者
        private OnSalePlan previousPlan;

        public DiscountPlan(int discount, OnSalePlan previousPlan) {
            this.discount = discount;
            this.previousPlan = previousPlan;
        }

        public DiscountPlan(int discount) {
            this(discount,NonePlan.INSTANCE);
        }

        @Override
        public float getPrice(float oldPrice) {
            //装饰器模式核心思想或者目的就是：重写某些方法，在装饰器的基础上进一步操作
            return previousPlan.getPrice(oldPrice) * discount / 10;
        }
    }

    public static void main(String[] args) {
        DiscountPlan simpleDiscountPlan = new DiscountPlan(5);//原价打五折
        System.out.println(simpleDiscountPlan.getPrice(100));

        KnockPlan knockPlan = new KnockPlan(50);//立减50
        DiscountPlan complexDiscountPlan = new DiscountPlan(5,knockPlan); //在立减优惠的基础上再打五折
        System.out.println(complexDiscountPlan.getPrice(100));

    }

}
